package com.example.literj.kt.core

import com.example.literj.kt.disposables.Disposable
import com.example.literj.kt.functions.Action
import com.example.literj.kt.functions.Consumer
import com.example.literj.kt.internal.functions.Functions
import com.example.literj.kt.internal.operators.LambdaObserver
import com.example.literj.kt.internal.operators.observable.ObservableCreate
import com.example.literj.kt.internal.operators.observable.ObservableJust
import com.example.literj.kt.plugins.RxJavaPlugins
import java.util.Objects

abstract class Observable<T> : ObservableSource<T> {
    companion object {
        @JvmStatic
        fun <T> create(source: ObservableOnSubscribe<T>): Observable<T> {
            return ObservableCreate(source)
        }

        @JvmStatic
        fun <T> just(item: T): Observable<T> {
            return ObservableJust(item)
        }
    }

    protected abstract fun subscribeActual(observer: Observer<T>)

    override fun subscribe(observer: Observer<T>) {
        Objects.requireNonNull(observer, "observer is null")
        try {
            var obsv = observer
            obsv = RxJavaPlugins.onSubscribe(this, obsv)
            subscribeActual(obsv)
        } catch (e: NullPointerException) {
            throw e
        } catch (e: Throwable) {
            RxJavaPlugins.onError(e)
        }
    }

/*    fun subscribe(
        onNext: Consumer<T>,
        onError: Consumer<in Throwable>,
        onComplete: Action
    ): Disposable {
        Objects.requireNonNull(onNext, "onNext is null")
        Objects.requireNonNull(onError, "onError is null")
        Objects.requireNonNull(onComplete, "onComplete is null")

        val ls = LambdaObserver(onNext, onError, onComplete, Functions.emptyConsumer())
        subscribe(ls)
        return ls;
    }*/
}